package com.roger.cmdkit.cases;

import com.roger.cmdkit.base.CmdBase;
import com.roger.cmdkit.util.ExcelUtil;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.roger.cmdkit.base.CmdHelper.getNextArg;

@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
public class BugAnalysis implements CmdBase {
    private ArrayList<String> key = new ArrayList<>();
    private ArrayList<String> summary = new ArrayList<>();

    private ArrayList<String> importance = new ArrayList<>();
    private ArrayList<String> status = new ArrayList<>();
    private ArrayList<String> resolution = new ArrayList<>();
    private ArrayList<String> reporter = new ArrayList<>();
    private ArrayList<String> assignee = new ArrayList<>();
    private ArrayList<String> component = new ArrayList<>();
    private ArrayList<String> created = new ArrayList<>();

    private ArrayList<String> SWReporter = new ArrayList<>();
    private ArrayList<String> manager = new ArrayList<>();
    private ArrayList<String> assignee0 = new ArrayList<>();
    private Map<String,String> assignees = new HashMap<>();
    private Map<String,Integer> components = new HashMap<>();

    private int [] today_s={0,0,0,0,0};
    private int [] status_s ={0,0,0,0,0};
    private int [] resolution_s ={0,0,0,0,0};
    private int [] timeout3_s ={0,0,0,0,0};
    private String today;

    @Override
    public void cmdS(String[] args) {
        System.out.println("Bug list analysis tool_V1.0.1");
        String file= getNextArg(args,"-path");
        today = getNextArg(args,"-today");
        if(today.equals("")) today = ExcelUtil.dateFormat.format(System.currentTimeMillis());
        if(!isDate(today)) { return; }
        getSWTestTeam();
        getManager();
        getAssignee();
        if(file.equals("")){
            File f = new File(System.getProperty("user.dir")+"\\BugList");
            File[] fList = f.listFiles();
            if(fList != null){
                for(File f1 : fList){
                    if(f1.isFile()){
                        String fName=f1.getName();
                        if(fName.substring(fName.lastIndexOf("."),fName.length()).equals(".xls")){
                            System.out.println("start analyse " + fName +"\n");
                            getData(f1.getAbsolutePath());
                            getResult();
                            getMResult();
                            getTop10Result();
                            getBlockResult();
                        }
                    }
                }
            }else{
                System.out.println("not find any files in BugList");
            }
        }else{
            System.out.println("start analyse " + file );
            getData(file);
            getResult();
            getMResult();
            getTop10Result();
            getBlockResult();
        }
    }

    private void getData(String file) {
        HSSFSheet st = ExcelUtil.getSheet(file,0);
        int rows = ExcelUtil.getAllRows(file, 0);
        for(int i = 4; i < rows; i++){
           if(st != null){
               HSSFRow row = st.getRow(i);
               HSSFCell cell= row.getCell((short) 0);
               if(cell.getStringCellValue().equals("Bug")){

                   HSSFCell cellKey= row.getCell((short) 1);
                   if (cellKey != null) {
                       cellKey.setEncoding(HSSFCell.ENCODING_UTF_16);
                       key.add(cellKey.getStringCellValue().equals("") ? "None" : cellKey.getStringCellValue());
                   }
                   HSSFCell cellSum= row.getCell((short) 2);
                   if (cellSum != null) {
                       cellSum.setEncoding(HSSFCell.ENCODING_UTF_16);
                       summary.add(cellSum.getStringCellValue().equals("") ? "None" : cellSum.getStringCellValue());
                   }

                   HSSFCell cell0= row.getCell((short) 3);
                   if (cell0 != null) {
                       cell0.setEncoding(HSSFCell.ENCODING_UTF_16);
                       importance.add(cell0.getStringCellValue().equals("") ? "None" : cell0.getStringCellValue());
                   }
                   HSSFCell cell1= row.getCell((short) 4);
                   if (cell1 != null) {
                       cell1.setEncoding(HSSFCell.ENCODING_UTF_16);
                       status.add(cell1.getStringCellValue().equals("") ? "None" : cell1.getStringCellValue());
                   }

                   HSSFCell cell2= row.getCell((short) 5);
                   if (cell2 != null) {
                       cell2.setEncoding(HSSFCell.ENCODING_UTF_16);
                       resolution.add(cell2.getStringCellValue().equals("") ? "None" : cell2.getStringCellValue());
                   }

                   HSSFCell cell3= row.getCell((short) 6);
                   if (cell3 != null) {
                       cell3.setEncoding(HSSFCell.ENCODING_UTF_16);
                       reporter.add(cell3.getStringCellValue().equals("") ? "None" : cell3.getStringCellValue());
                   }

                   HSSFCell cell4= row.getCell((short) 7);
                   if (cell4 != null) {
                       cell4.setEncoding(HSSFCell.ENCODING_UTF_16);
                       assignee.add(cell4.getStringCellValue().equals("") ? "None" : cell4.getStringCellValue());
                   }

                   HSSFCell cell5= row.getCell((short) 9);
                   if (cell5!= null) {
                       cell5.setEncoding(HSSFCell.ENCODING_UTF_16);
                       Date date = cell5.getDateCellValue();
                       if (date != null) {
                           created.add(ExcelUtil.dateFormat.format(cell5.getDateCellValue()));
                       }else{
                           created.add("2000/01/01");
                       }
                   }

                   HSSFCell cell6= row.getCell((short) 8);
                   if (cell6 != null && cell1 != null && cell3 != null && (cell1.getStringCellValue().equals("") ? "None" : cell1.getStringCellValue()).matches("(?i)New|In Progress|Reopened|WaitForInfo") && SWReporter.contains(cell3.getStringCellValue().equals("") ? "None" : cell3.getStringCellValue())) {
                       cell6.setEncoding(HSSFCell.ENCODING_UTF_16);
                       component.add(cell6.getStringCellValue().equals("") ? "None" : cell6.getStringCellValue());
                   }
               }
           }
        }
    }

    private void getResult(){
        for(int i=0;i<created.size();i++){
            if(SWReporter.contains(reporter.get(i))){
                if (importance.get(i).equals("Blocker(S1)") && created.get(i).equals(today)) today_s[0] ++;
                if (importance.get(i).equals("Critical(S2)") && created.get(i).equals(today)) today_s[1] ++;
                if (importance.get(i).equals("Major(S3)") && created.get(i).equals(today)) today_s[2] ++;
                if (importance.get(i).equals("Minor(S4)") && created.get(i).equals(today)) today_s[3] ++;
            }

            if (importance.get(i).equals("Blocker(S1)") && status.get(i).equals("Review Won't Fix")) status_s[0] ++;
            if (importance.get(i).equals("Critical(S2)") && status.get(i).equals("Review Won't Fix")) status_s[1] ++;
            if (importance.get(i).equals("Major(S3)") && status.get(i).equals("Review Won't Fix")) status_s[2] ++;
            if (importance.get(i).equals("Minor(S4)") && status.get(i).equals("Review Won't Fix")) status_s[3] ++;

            if (importance.get(i).equals("Blocker(S1)") && resolution.get(i).equals("Won't Do")) resolution_s[0] ++;
            if (importance.get(i).equals("Critical(S2)") && resolution.get(i).equals("Won't Do")) resolution_s[1]++;
            if (importance.get(i).equals("Major(S3)") && resolution.get(i).equals("Won't Do")) resolution_s[2] ++;
            if (importance.get(i).equals("Minor(S4)") && resolution.get(i).equals("Won't Do")) resolution_s[3] ++;

            if (importance.get(i).equals("Blocker(S1)") && timeout3(created.get(i)) && status.get(i).matches("(?i)New|In Progress|Reopened|WaitForInfo")) timeout3_s[0] ++;
            if (importance.get(i).equals("Critical(S2)") && timeout3(created.get(i)) && status.get(i).matches("(?i)New|In Progress|Reopened|WaitForInfo")) timeout3_s[1] ++;
            if (importance.get(i).equals("Major(S3)") && timeout3(created.get(i)) && status.get(i).matches("(?i)New|In Progress|Reopened|WaitForInfo")) timeout3_s[2] ++;
            if (importance.get(i).equals("Minor(S4)") && timeout3(created.get(i)) && status.get(i).matches("(?i)New|In Progress|Reopened|WaitForInfo")) timeout3_s[3] ++;
        }
        today_s[4] = today_s[0]+today_s[1]+today_s[2]+today_s[3];
        status_s[4]=status_s[0]+status_s[1]+status_s[2]+status_s[3];
        resolution_s[4]=resolution_s[0]+resolution_s[1]+resolution_s[2]+resolution_s[3];
        timeout3_s[4]=timeout3_s[0]+timeout3_s[1]+timeout3_s[2]+timeout3_s[3];

        addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,2, (short) (0),String.valueOf(today));
        addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,6, (short) (0),String.valueOf(today));
        addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,10, (short) (0),String.valueOf(today));
        addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,14, (short) (0),String.valueOf(today));

        System.out.print("today new Bug :");System.out.print(today_s[0] +",");System.out.print(today_s[1] +",");System.out.print(today_s[2] +",");System.out.print(today_s[3] +",");System.out.println(today_s[4]);
        for (int i =0; i<today_s.length;i++)
            ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,2, (short) (i+1),String.valueOf(today_s[i]));
        System.out.print("Review Won't Fix Bug :");System.out.print(status_s[0] +",");System.out.print(status_s[1] +",");System.out.print(status_s[2] +",");System.out.print(status_s[3] +",");System.out.println(status_s[4]);
        for (int i =0; i<status_s.length;i++)
            ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,6, (short) (i+1),String.valueOf(status_s[i]));
        System.out.print("Won't do Bug :");System.out.print(resolution_s[0] +",");System.out.print(resolution_s[1] +",");System.out.print(resolution_s[2] +",");System.out.print(resolution_s[3] +",");System.out.println(resolution_s[4]);
        for (int i =0; i<resolution_s.length;i++)
            ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,10, (short) (i+1),String.valueOf(resolution_s[i]));
        System.out.print("timeout 3 days Bug :");System.out.print(timeout3_s[0] +",");System.out.print(timeout3_s[1] +",");System.out.print(timeout3_s[2]+",");System.out.print(timeout3_s[3] +",");System.out.println(timeout3_s[4]+"\n");
        for (int i =0; i<timeout3_s.length;i++)
            ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,14, (short) (i+1),String.valueOf(timeout3_s[i]));
    }

    private void getMResult(){
        int rows = ExcelUtil.getAllRows(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2);
        for(int a =0 ;a< manager.size();a++){
            int [] manager_s= {0,0,0,0,0};
            for(int i=0;i<created.size();i++){
                if( assignee0.contains(assignee.get(i))){
                    if (importance.get(i).equals("Blocker(S1)")  && status.get(i).matches("(?i)New|In Progress|Reopened") && assignees.get(assignee.get(i)).equals(manager.get(a)) ) manager_s[0]++;
                    if (importance.get(i).equals("Critical(S2)")  && status.get(i).matches("(?i)New|In Progress|Reopened")  && assignees.get(assignee.get(i)).equals(manager.get(a))) manager_s[1]++;
                    if (importance.get(i).equals("Major(S3)")  && status.get(i).matches("(?i)New|In Progress|Reopened")  && assignees.get(assignee.get(i)).equals(manager.get(a))) manager_s[2]++;
                    if (importance.get(i).equals("Minor(S4)")  && status.get(i).matches("(?i)New|In Progress|Reopened") && assignees.get(assignee.get(i)).equals(manager.get(a)) ) manager_s[3]++;
                }
            }
            manager_s[4]= manager_s[0] + manager_s[1] + manager_s[2] + manager_s[3];
            System.out.print(manager.get(a)+":");System.out.print(manager_s[0] +",");
            System.out.print(manager_s[1] +",");System.out.print(manager_s[2] +",");
            System.out.print(manager_s[3] +",");System.out.println(manager_s[4]);

            for(int m = 0;m <= rows;m++){
                String s = ExcelUtil.getExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,m,(short)0);
                if( s.equals(manager.get(a))) {
                    for (int j =0; j < manager_s.length;j++){
                        ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,m, (short) (j+1),String.valueOf(manager_s[j]));
                    }
                }
            }
        }
        System.out.print("\n");
    }

    private void getTop10Result(){
        int rows = ExcelUtil.getAllRows(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2);
        int first = 0;
        getListElements(component);
        ArrayList<Map.Entry<String,Integer>> list = new ArrayList<>( components.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String,Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> stringIntegerEntry, Map.Entry<String, Integer> t1) {
                return t1.getValue().compareTo(stringIntegerEntry.getValue());
            }
        });

        for(int m = 0;m <= rows;m++){
            String s = ExcelUtil.getExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,m,(short)0);
            if( s.equals("NO.")){
               first=m;
               break;
            }
        }

        for (Map.Entry<String,Integer> mapping : list.subList(0,10)) {
            System.out.println(mapping.getKey() + ":" + mapping.getValue());
            addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,first+1, (short)(1),String.valueOf(mapping.getKey()));
            ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",2,first+1, (short)(2),String.valueOf(mapping.getValue()));
            first++;
        }
        System.out.print("\n");
    }

    @SuppressWarnings("ResultOfMethodCallIgnored")
    private void getBlockResult(){
        int count=0;
        File f = new File(System.getProperty("user.dir")+"\\Model\\New_Block.xls");
        if(f.exists()) f.delete();
        String [] titles = {"Key","Summary","Importance","Assignee"};
        ExcelUtil.createExcel(System.getProperty("user.dir")+"\\Model\\New_Block.xls",titles);
        for(int i=0;i<key.size();i++){
            if (importance.get(i).equals("Blocker(S1)")  && created.get(i).equals(today) ){
                count++;
                System.out.println("today block bug key:"+count+"  "+key.get(i));
                ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\New_Block.xls",0,count, (short) (0),String.valueOf(key.get(i)));
                ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\New_Block.xls",0,count, (short) (1),String.valueOf(summary.get(i)));
                ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\New_Block.xls",0,count, (short) (2),String.valueOf(importance.get(i)));
                ExcelUtil.addExcelData(System.getProperty("user.dir")+"\\Model\\New_Block.xls",0,count, (short) (3),String.valueOf(assignee.get(i)));
            }
        }
    }

    private Boolean timeout3(String created){
        try {
            long from= ExcelUtil.dateFormat.parse(created).getTime();
            long to = ExcelUtil.dateFormat.parse(today).getTime();
            int days = (int) ((to - from) / (1000 * 60 * 60 * 24));
            if(days > 3) return true;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return false;
    }

    private Boolean isDate(String s){
        try {
            ExcelUtil.dateFormat.parse(s);
            return true;
        } catch (ParseException e) {
            System.out.println("-today should like: 2020/01/01");
            return false;
        }
    }

    //get all SW Test Team reporters
    private void getSWTestTeam(){
        int rows = ExcelUtil.getAllRows(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",4);
        for(int i = 1;i <= rows;i++){
            String s = ExcelUtil.getExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",4,i,(short)3);
            if(!s.equals("") && ! SWReporter.contains(s)) SWReporter.add(s);
        }
    }

    // get all managers
    private void getManager(){
        int rows = ExcelUtil.getAllRows(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",5);
        for(int i = 1;i <= rows;i++){
            String s = ExcelUtil.getExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",5,i,(short)2);
            if( !s.equals("") && ! manager.contains(s)) manager.add(s);
        }
    }

    // get all assignee
    private void getAssignee(){
        int rows = ExcelUtil.getAllRows(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",5);
        for(int i = 1;i <= rows;i++){
            String s = ExcelUtil.getExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",5,i,(short)2);
            String s1 = ExcelUtil.getExcelData(System.getProperty("user.dir")+"\\Model\\Test_Report.xls",5,i,(short)3);
            if( !s1.equals("") && ! assignee0.contains(s1)) {
                assignee0.add(s1);
                assignees.put(s1,s);
            }
        }
    }

    private void getListElements ( ArrayList<String> items ) {
        if (items == null || items.size() == 0) return;
        for (String temp : items) {
            Integer count = components.get(temp);
            components.put(temp, (count == null) ? 1 : count + 1);
        }
    }

    private void addExcelData(String file,int sheet,int rows,short cols,String text) {
        try {
            File f = new File(file);
            FileInputStream fis=new FileInputStream(f);
            BufferedInputStream bis = new BufferedInputStream(fis);
            POIFSFileSystem fs = new POIFSFileSystem(bis);
            HSSFWorkbook wb = new HSSFWorkbook(fs);

            HSSFFont font = wb.createFont();
            font.setFontName(new String("微软雅黑".getBytes("gbk"),"utf-8"));
            HSSFCellStyle style = wb.createCellStyle();
            style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
            style.setFont(font);
            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);

            HSSFSheet st = wb.getSheetAt(sheet);
            HSSFRow row = st.createRow(rows);
            HSSFCell cell = row.createCell(cols);
            cell.setEncoding(HSSFCell.ENCODING_UTF_16);
            cell.setCellType(HSSFCell.CELL_TYPE_STRING);
            cell.setCellStyle(style);
            cell.setCellValue(text);

            FileOutputStream fos = new FileOutputStream(file);
            wb.write(fos);
            fos.flush();
            fos.close();
            bis.close();
            fis.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //list managers,no use
    private String getManagers(String assignee){
        switch (assignee){
            case  "宋祎斐":  case  "白栋霖":  case  "王惠":
            case  "赵晶":  case  "傅举峰":  case  "姜万勇":
            case  "付维坤":  case  "刘鑫全":  case  "王晔":
            case  "戚玉顺":  case  "李兆安":  case  "彭绍平":
            case  "TS-BSP-晋鹏":  case  "TS-BSP-何耀":  case  "TS-BSP-顾学伟":
            case  "TS-BSP-贾浩":  case  "TS-BSP-耿培俊":  case  "TS-BSP-陈斐":
            case  "TS-BSP-韩启伟":  case  "TS-BSP-李明":
                return "宋祎斐";
            case  "余勇":  case  "傅彬":  case  "刘梁":
            case  "朱涛":  case  "TS-MODEM-付小华":  case  "TS-TELE-梅双文":
            case  "TS-TELE-郑从隆":
                return "余勇";
            case  "陈涌":  case  "李丽云":  case  "王蒙蒙":
            case  "吴凤龙":  case  "宋华":  case  "刘举奎":
            case  "甄凯峰":  case  "TS-FW-蒋国虎":  case  "TS-FW-万君彦":
            case  "TS-FW-毕伟":  case  "TS-FW-孙飞":  case  "TS-FW-任康":
                return "陈涌";
            case  "张晓丹":  case  "王坤":  case  "邱云龙":
            case  "陈晓龙":  case  "付助荣":  case  "TS-CAMERA-余金云":
            case  "TS-CAMERA-薛文翰":  case  "TS-CAMERA-李道冲":  case  "TS-CAMERA-周以宽":
            case  "TS_CAMERATUNING-孙梦晓":
                return "张晓丹";
            case  "韦建龙":  case  "侯杰":  case  "余龙":
            case  "王小毛":  case  "李大业":  case  "王凤芝":
            case  "金迪":  case  "杨习平":  case  "梁亚楠":
            case  "李远征":  case  "宋建华":  case  "宋姝羽":
                return "韦建龙";
            case  "周大凯":  case  "程文彬":  case  "赵小杰":
            case  "王一发":  case  "金城":  case  "许海宾":
            case  "钟立敏":  case  "朱华建":  case  "黄永标":
            case  "胡捷":  case  "王小龙":  case  "白俊彦":
                return "周大凯";
            case  "贺峰":  case  "李明柱":  case  "李艳霞":
            case  "周文塨":  case  "董梦林":  case  "王文永":
                return "贺峰";
            case  "任天舒":  case  "TS-APP-章凤":  case  "TS-APP-惠莹民":
            case  "TS-APP-袁沅芳":  case  "TS-APP-张煜":  case  "TS-APP-袁野":
            case  "TS-APP-李从龙":  case  "TS-APP-谢伟":  case  "TS-APP-许兵兵":
            case  "TS-APP-罗浩宇":  case  "TS-APP-周廖宇":  case  "TS-APP-闻杰":
            case  "TS-APP-王魁":  case  "TS-APP-王项雨":  case  "TS-APP-诸雪琴":
            case  "TS-APP-张亮":  case  "TS-APP-王洁":  case  "TS-APP-郭如祎":
            case  "TS-APP-高晨":
                return "任天舒";
            case  "张泽华":  case  "bing_xanzh":  case  "aidujia_QA_xianxian":
            case  "张苧方":  case  "高岚":  case  "汪莎莎":
            case  "陈金":
                return "Jason";
            case  "HQ_SW_谭程天":  case  "HQ_SW_刘剑": case  "HQ_SW_刘一波":
            case  "HQ_SW_吴建平": case  "HQ_SW_冯凯":  case  "HQ_SW_胡乾":
            case  "HQ_SW_王维": case  "HQ_SW_邓志勇":
                return "刘婧";
            default:
                return "";
        }
    }

}
